package com.computergames.server;

import com.computergames.server.config.Config;
import com.computergames.server.message.CreateRoomRequestMessage;
import com.computergames.server.message.CreateRoomResponseMessage;
import com.computergames.server.protocol.MessageCodecSharable;
import com.computergames.server.protocol.ProtocolFrameDecoder;
import com.computergames.server.server.session.Room;
import com.computergames.server.server.session.RoomSessionFactory;
import com.computergames.server.server.session.RoomSessionService;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class Server {
    private ThreadPoolExecutor threadPoolExecutor;
    public void start(){
        LoggingHandler LOGGING_HANDLER = new LoggingHandler(LogLevel.INFO);
        MessageCodecSharable MESSAGE_CODEC = new MessageCodecSharable();
        NioEventLoopGroup boss = new NioEventLoopGroup(1);
        NioEventLoopGroup worker = new NioEventLoopGroup(6);

        // 初始化线程池
        threadPoolExecutor = new ThreadPoolExecutor(
                10, // 核心线程数
                Runtime.getRuntime().availableProcessors() * 2 + 2, // 最大线程数
                60, // 空闲线程存活时间（秒）
                TimeUnit.SECONDS,
                new java.util.concurrent.LinkedBlockingQueue<>(Integer.MAX_VALUE) // 队列大小
        );
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(boss, worker)
                    .channel(NioServerSocketChannel.class)
                    //设置在连接建立之前（服务器触发accept事件之前）能够排队的连接请求数量，根据系统资源进行合理设置
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    //检测底层TCP连接是否存活，在长时间没有数据传输的情况下，系统会自动发送keepalive探测包，保持长连接
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new ProtocolFrameDecoder());
                            ch.pipeline().addLast(LOGGING_HANDLER);
                            ch.pipeline().addLast(MESSAGE_CODEC);
                            ch.pipeline().addLast(new SimpleChannelInboundHandler<CreateRoomRequestMessage>() {
                                @Override
                                protected void channelRead0(ChannelHandlerContext channelHandlerContext, CreateRoomRequestMessage msg) throws Exception {
                                    String roomName = msg.getRoomName();
                                    String roomType = msg.getRoomType();
                                    List<String> members = msg.getMembers();
                                    RoomSessionService roomSessionService = RoomSessionFactory.getRoomSession();

                                    threadPoolExecutor.execute(() -> {
                                        int[] array = {64, 34, 25, 12, 22, 11, 90};
                                        int n = array.length;
                                        boolean swapped;
                                        for (int i = 0; i < n - 1; i++) {
                                            swapped = false;
                                            for (int j = 0; j < n - 1 - i; j++) {
                                                if (array[j] > array[j + 1]) {
                                                    // 交换 array[j] 和 array[j+1]
                                                    int temp = array[j];
                                                    array[j] = array[j + 1];
                                                    array[j + 1] = temp;
                                                    swapped = true;
                                                }
                                            }
                                            // 如果没有发生交换，说明数组已经有序，提前结束
                                            if (!swapped) {
                                                break;
                                            }
                                        }
                                        Room room = roomSessionService.createRoom(roomName, roomType, members);
                                        channelHandlerContext.writeAndFlush(new CreateRoomResponseMessage(true, roomName + "创建成功"));
                                    });



                                }
                            });
                        }
                    });
            ChannelFuture channelFuture = serverBootstrap.bind(8082).sync();
            channelFuture.channel().closeFuture().sync();
        }catch (InterruptedException e){
            log.error("server error", e);
        }finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }
}
